/*
 * sequential_worker.h
 *
 *  Created on: 2016年2月25日
 *      Author: Administrator
 */

#ifndef CORE_SOURCES_PROCESS_SEQUENTIAL_WORKER_H_
#define CORE_SOURCES_PROCESS_SEQUENTIAL_WORKER_H_
#include <queue>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>
#include "../conf/def.h"
#include "gc/gc.h"
#include "thread_task_base.hpp"
#include "thread_task.hpp"
namespace eyas{
namespace thread{

class EYAS_THREAD_API sequential_task : public boost::enable_shared_from_this<sequential_task> {
public:
	sequential_task();
	virtual ~sequential_task();
private:
	bool active_;
	bool disposed_;
	// 互斥信号量
	boost::mutex mutex_;
	boost::condition_variable cond_var_;
	// 任务队列
	typedef std::queue<thread_task_ptr> task_queue;
	// 任务队列
	task_queue task_queue_;
private:
	// 非现场安全，须在互斥区域内调用
	void _check_active();
	void sequential_task_proc();
	// 销毁
	void dispose();

	template<typename F>
	void schedule_ref(EYAS_THREAD_RV_REF(F) taskFunc);
public:
	template<typename F, typename... Args>
	void schedule(F taskFunc, Args... args);
protected:
	//
	// thread_task_base
	//
	virtual void on_task();
};
typedef boost::shared_ptr<sequential_task> sequential_task_ptr;

template<typename F>
void sequential_task::schedule_ref(EYAS_THREAD_RV_REF(F) taskFunc){
	boost::mutex::scoped_lock lock(mutex_);
	if(this->disposed_){
		return;
	}
	//thread_task<F>* task = thread_task<F>::create_new(taskFunc);
	thread_task_ptr taskPtr = eyas::gc::create_new<thread_task<F>>(taskFunc);
	this->task_queue_.push(taskPtr);
	this->_check_active();
}
template<typename F, typename... Args>
void sequential_task::schedule(F taskFunc, Args... args){
	this->schedule_ref(boost::bind(taskFunc, args...));
}

}
}
#endif /* CORE_SOURCES_PROCESS_SEQUENTIAL_WORKER_H_ */
